package com.github.xzb617.adm.controller;

import com.github.xzb617.adm.service.UserService;
import com.github.xzb617.common.util.StrUtil;
import com.github.xzb617.constant.SuperAdminConstant;
import com.github.xzb617.domain.common.AjaxResponse;
import com.github.xzb617.domain.dto.LoginDTO;
import com.github.xzb617.domain.entity.User;
import com.github.xzb617.domain.vo.LoginResult;
import com.github.xzb617.domain.vo.UserVO;
import com.github.xzb617.props.SecurityProperties;
import com.github.xzb617.security.Subject;
import com.github.xzb617.security.SubjectHolder;
import com.github.xzb617.security.token.TokenManager;
import com.github.xzb617.utils.PasswordEncryptor;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 登录认证
 * @author xzb617
 */
@RestController
@RequestMapping("/auth")
public class AuthController {

    private final UserService userService;
    private final TokenManager tokenManager;
    private final SecurityProperties securityProperties;

    public AuthController(UserService userService, TokenManager tokenManager, SecurityProperties securityProperties) {
        this.userService = userService;
        this.tokenManager = tokenManager;
        this.securityProperties = securityProperties;
    }

    /**
     * 用户登录
     * @param dto 登录参数
     * @return LoginResult
     */
    @PostMapping("/login")
    public AjaxResponse login(@RequestBody @Validated LoginDTO dto) {
        // 查询用户
        User user = this.userService.getByName(dto.getUsername());
        if (user == null) {
            return AjaxResponse.failure("用户名或密码错误");
        }
        // 校验密码
        boolean matched = PasswordEncryptor.match(user.getPassword(), dto.getPassword(), this.securityProperties.getUserPasswordEncryptedSecret(), user.getSalt());
        if (!matched) {
            return AjaxResponse.failure("用户名或密码错误");
        }
        // 用户角色
        String role = user.getRole();
        // 生成令牌
        String token = this.tokenManager.createToken(user);
        // 返回登录结果
        return AjaxResponse.success()
                .message("登录成功")
                .data(new LoginResult(token, user.getId(), user.getUsername(), new Date(), StrUtil.strToSet(role)));
    }


    /**
     * 用户登出
     * @return
     */
    @DeleteMapping("/logout")
    public AjaxResponse logout() {
        return AjaxResponse.success().message("登出成功");
    }


    /**
     * 获取当前登录用户的数据
     * 必须持有令牌才能访问接口
     * @return
     */
    @GetMapping("/getInfo")
    public AjaxResponse getInfo() {
        // 解析令牌
        Subject subject = SubjectHolder.getContext();
        // 设置返回信息
        Set<String> roles = StrUtil.strToSet(subject.getRole());
        Map<String, Object> data = new HashMap<>(2);
        data.put("username", subject.getUsername());
        data.put("roles", roles);
        return AjaxResponse.success()
                .message("查询成功").data(data);
    }

    @GetMapping("/getSelf")
    public AjaxResponse getSelf() {
        Subject subject = SubjectHolder.getContext();
        User user = this.userService.getByName(subject.getUsername());
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return AjaxResponse.success().data(userVO);
    }
}
